package com.sys.object.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import sun.misc.BASE64Decoder;

/**
 * Created by 小脸通红 on 9/19/15.
 */
public class Base64Helper {
    private static final Logger logger = LoggerFactory.getLogger(Base64Helper.class);

    private static String Base64ImageHeader = "data:image/(.*);base64,(.*)";
    private static String Base64ExcelHeader03 = "data:application/vnd.ms-excel;base64,(.*)";
    private static String Base64ExcelHeader0302 = "data:application/msexcel;base64,(.*)";
    private static String Base64ExcelHeader07 = "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,(.*)";

    public static String getImageFromBASE64(String path,String fileData) throws Exception {

        if(fileData == null)
            return null;
        if(!fileData.matches(Base64ImageHeader))
            return null;
        fileData = fileData.substring(fileData.indexOf(',') + 1);
        String fileName =  UUID.randomUUID().toString();
        String pathName = getRelativelyPath() +path + fileName;

        BASE64Decoder decoder = new BASE64Decoder();
        FileOutputStream write = new FileOutputStream(new File(pathName));
        byte[] decoderBytes = decoder.decodeBuffer(fileData);
        write.write(decoderBytes);
        write.close();

        return path + fileName;
    }
    
    public static byte[] getImageFromBASE64ToByte(String fileData) throws Exception {

        if(!StringUtils.hasText(fileData))
            return null;
        if(!fileData.matches(Base64ImageHeader))
            return null;
        fileData = fileData.substring(fileData.indexOf(',') + 1);
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] decoderBytes = decoder.decodeBuffer(fileData);
        if(decoderBytes.length>0){
        	return decoderBytes;
        }
        return null;
    }
    
    public static String getExcelFromBASE64(String path,String fileData) throws Exception {

        try {
            if(fileData == null)
                throw new Exception("文件数据不正确") ;
            if(!fileData.matches(Base64ExcelHeader03)&&!fileData.matches(Base64ExcelHeader0302))
                throw new Exception("文件格式不正确") ;
            fileData = fileData.substring(fileData.indexOf(',') + 1);

            File file=new File(getRelativelyPath()+path);
            if(!file.exists()) {
                file.mkdir();
            }

            String fileName =  UUID.randomUUID().toString();
            String pathName = getRelativelyPath() +path + fileName;
            BASE64Decoder decoder = new BASE64Decoder();
            FileOutputStream write = new FileOutputStream(new File(pathName));
            byte[] decoderBytes = decoder.decodeBuffer(fileData);
            write.write(decoderBytes);
            write.close();

            return pathName;

        }catch (Exception e){
            logger.error(e.getMessage(), e);
            throw new Exception("数据文件格式不正确");
        }
    }
    
    public static String getFileFromBASE64(String path,String filename,String fileData) throws Exception {

        try {
            if(fileData == null)
                throw new Exception("文件数据不正确") ;
            fileData = fileData.substring(fileData.indexOf(',') + 1);
            File file=new File(getRelativelyPath()+path);
            if(!file.exists()) {
                file.mkdir();
            }
            String fileName =  UUID.randomUUID().toString()+""+filename.substring(filename.lastIndexOf("."), filename.length());
            String pathName = getRelativelyPath() +path + fileName;
            BASE64Decoder decoder = new BASE64Decoder();
            FileOutputStream write = new FileOutputStream(new File(pathName));
            byte[] decoderBytes = decoder.decodeBuffer(fileData);
            write.write(decoderBytes);
            write.close();

            return path+fileName;

        }catch (Exception e){
            logger.error(e.getMessage(), e);
            throw new Exception("数据文件格式不正确");
        }

    }

    public static String getFileFromBASE64WithRealFileName(String path,String filename,String fileData) throws Exception {

        try {
            if(fileData == null)
                throw new Exception("文件数据不正确") ;
            fileData = fileData.substring(fileData.indexOf(',') + 1);
            File file=new File(getRelativelyPath()+path);
            if(!file.exists()) {
                file.mkdir();
            }
            file=new File(getRelativelyPath()+path+filename);
            String fileNameWithoutExt=filename.substring(0,filename.lastIndexOf("."));
            String ext=fileExt(filename);
            int i=1;
            while (file.exists()){
                file=new File(getRelativelyPath()+path+fileNameWithoutExt+"("+i+")"+ext);
                i++;
            }
            BASE64Decoder decoder = new BASE64Decoder();
            FileOutputStream write = new FileOutputStream(file);
            byte[] decoderBytes = decoder.decodeBuffer(fileData);
            write.write(decoderBytes);
            write.close();
            return path+file.getName();

        } catch (Exception e){
            logger.error(e.getMessage(), e);
            throw new Exception("数据文件格式不正确");
        }
    }

    
    public static byte[] getExcelFromBASE64(String fileData) throws Exception {
        try {
            if(fileData == null)
                throw new Exception("文件数据不正确") ;
            if(!fileData.matches(Base64ExcelHeader03)&&!fileData.matches(Base64ExcelHeader0302))
                throw new Exception("文件格式不正确") ;
            fileData = fileData.substring(fileData.indexOf(',') + 1);
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] decoderBytes = decoder.decodeBuffer(fileData);
            return decoderBytes;

        }catch (Exception e){
            logger.error(e.getMessage(), e);
            throw new Exception("数据文件格式不正确");
        }
    }
    
    public static byte[] getFileFromBASE64(String fileData) throws Exception {
        try {
            if(fileData == null)
                throw new Exception("文件数据不正确") ;
            if(!matchesFile(fileData))
                throw new Exception("文件格式不正确") ;
            fileData = fileData.substring(fileData.indexOf(',') + 1);
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] decoderBytes = decoder.decodeBuffer(fileData);
            return decoderBytes;

        } catch (Exception e){
            logger.error(e.getMessage(), e);
            throw new Exception("数据文件格式不正确");
        }
    }
    
    


    public static String updateImageFromBase64(String url, String path, String fileData) throws Exception{

        try {
            if(fileData == null)
                throw new Exception("文件数据不正确") ;
            if(!fileData.matches(Base64ImageHeader))
                throw new Exception("文件格式不正确") ;
            fileData = fileData.substring(fileData.indexOf(',') + 1);

            File file=new File(getRelativelyPath()+path);
            if(!file.exists()) {
                file.mkdir();
            }

            String fileName =  UUID.randomUUID().toString();
            String pathName = getRelativelyPath() + path + fileName;
            BASE64Decoder decoder = new BASE64Decoder();
            FileOutputStream write = new FileOutputStream(new File(pathName));
            byte[] decoderBytes = decoder.decodeBuffer(fileData);
            write.write(decoderBytes);
            write.close();
            if(url!=null){
                String originalName = getRelativelyPath() + url;
                File of = new File(originalName);
                if(of.exists()) of.delete();
            }
            return path + fileName;

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }
    
    public static boolean matchesFile(String fileData){
    	if(fileData.matches(Base64ImageHeader))
    		return true;
    	if(fileData.matches(Base64ExcelHeader03))
    		return true;
        if(fileData.matches(Base64ExcelHeader0302))
            return true;
    	if(fileData.matches(Base64ExcelHeader07))
    		return true;
    	return false;
    }
    
    /**
     * 获取文件后缀
     * @param filename
     * @return
     */
    public static String fileExt(String filename){
    	if(StringUtils.hasText(filename)&&filename.lastIndexOf(".")!=-1){
    		return filename.substring(filename.lastIndexOf("."), filename.length());
    	}
    	return null;
    }
    
    public static String getRelativelyPath(){

        try {
            String cp = new File(Base64Helper.class.getResource("/").getFile()).getParentFile().getCanonicalPath();
            cp = cp.substring(0,cp.length()-7);
            return cp;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ".";
    }
    
    public static byte[] inputStreamToBytes(InputStream data) {

		byte[] requestbyte = null;
		try {
			DataInputStream in = new DataInputStream(data);
			byte[] b = new byte[1024];
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			int length = 0;
			while ((length = in.read(b)) != -1) {
				bout.write(b, 0, length);
			}
			requestbyte = bout.toByteArray();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.info("数据解析错误=" + e.getMessage());
			return null;
		}
		return requestbyte;
	}
    
    public static void main(String[] args){
    	System.out.println(DigestUtils.md5Hex("123456"));
    }
}
